﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ShevaEngine.Core.Modules.Graphics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using ShevaEngine.Core.Modules.Materials;
using ShevaEngine.Core.Interfaces;

namespace ShevaEngine.Core.Foundation.GraphicsObjects
{
    /// <summary>
    /// Drawing class.
    /// </summary>
    public class Drawing
    {
        /// <summary>Singleton.</summary>
        public static readonly Drawing Instance = new Drawing();

        /// <summary>Circle segments count.</summary>
        public const Int32 CircleSegmentsCount = 125;

        /// <summary>Material.</summary>
        public DrawCallKey DrawCallKey;
        /// <summary>Material.</summary>
        public DrawCallKey DrawCallKeyTextured;
        /// <summary>Circle draw call.</summary>
        public UserPrimitivesDrawCall<VertexPositionColor> CircleDrawCall;
        /// <summary>Circle draw call.</summary>
        public UserPrimitivesDrawCall<VertexPositionColor> RectangleDrawCall;
        /// <summary>Circle draw call.</summary>
        public UserPrimitivesDrawCall<VertexPositionTexture> RectangleTexturedDrawCall;

        /// <summary>
        /// Konstruktor.
        /// </summary>
        private Drawing()
        {
            this.DrawCallKey = new
                DrawCallKey(
                    MaterialManager.Instance.GetMaterialID("MaterialBaseColor"),
                    DrawCallKey.None,
                    DrawCallKey.None,
                    DrawCallKey.None);

            this.DrawCallKeyTextured = new
                DrawCallKey(
                    MaterialManager.Instance.GetMaterialID("MaterialBaseVertexTextured"),
                    DrawCallKey.None,
                    DrawCallKey.None,
                    DrawCallKey.None);
            

            VertexPositionColor[] vertices = new VertexPositionColor[Drawing.CircleSegmentsCount];

            for (int i = 0; i < Drawing.CircleSegmentsCount; i++)
                vertices[i] = new VertexPositionColor(
                    new Vector3(
                        (float)Math.Sin((i * (MathHelper.Pi * 2.0f) / (Drawing.CircleSegmentsCount - 1))),
                        0,
                        (float)Math.Cos((i * (MathHelper.Pi * 2.0f) / (Drawing.CircleSegmentsCount - 1)))),
                    Color.YellowGreen);

            this.CircleDrawCall = new UserPrimitivesDrawCall<VertexPositionColor>(
                PrimitiveType.LineStrip, vertices, Drawing.CircleSegmentsCount - 1);            

            
            vertices = new VertexPositionColor[5];

            vertices[0] = new VertexPositionColor(new Vector3(-1, 0, -1), Color.White);
            vertices[1] = new VertexPositionColor(new Vector3(1, 0, -1), Color.White);
            vertices[2] = new VertexPositionColor(new Vector3(1, 0, 1), Color.White);
            vertices[3] = new VertexPositionColor(new Vector3(-1, 0, 1), Color.White);
            vertices[4] = new VertexPositionColor(new Vector3(-1, 0, -1), Color.White);

            this.RectangleDrawCall = new UserPrimitivesDrawCall<VertexPositionColor>(
                PrimitiveType.LineStrip, vertices, 4);


            VertexPositionTexture[] verticesT = new VertexPositionTexture[4];

            verticesT[0] = new VertexPositionTexture(new Vector3(-1, 0, -1), new Vector2(0, 0));
            verticesT[1] = new VertexPositionTexture(new Vector3(1, 0, -1), new Vector2(1, 0));
            verticesT[2] = new VertexPositionTexture(new Vector3(-1, 0, 1), new Vector2(0, 1));
            verticesT[3] = new VertexPositionTexture(new Vector3(1, 0, 1), new Vector2(1, 1));

            this.RectangleTexturedDrawCall = new UserPrimitivesDrawCall<VertexPositionTexture>(
                PrimitiveType.TriangleStrip, verticesT, 2);            
        }

        /// <summary>
        /// Method draws line.
        /// </summary>
        /// <param name="pipeline"></param>
        /// <param name="startVertex"></param>
        /// <param name="endVertex"></param>
        public DrawCall CreateLine(Vector3 startVertex, Vector3 endVertex)
        {
            UserPrimitivesDrawCall<VertexPositionColor> lineDrawCall = new UserPrimitivesDrawCall<VertexPositionColor>(
                PrimitiveType.LineList, new VertexPositionColor[] { 
                new VertexPositionColor(startVertex, Color.White), 
                new VertexPositionColor(endVertex, Color.White) }, 1);            

            return lineDrawCall;
        }

        /// <summary>
        /// Method draws circle.
        /// </summary>
        /// <param name="pipeline"></param>
        /// <param name="centerPosition"></param>
        /// <param name="color"></param>
        public DrawCall CreateCircle()
        {
            return this.CircleDrawCall;
        }

        /// <summary>
        /// Method creates rectangle.
        /// </summary>
        /// <param name="pipeline"></param>
        /// <param name="centerPosition"></param>
        /// <param name="color"></param>
        public DrawCall CreateRectangle()
        {
            return this.RectangleDrawCall;
        }

        /// <summary>
        /// Method creates rectangle.
        /// </summary>
        /// <param name="pipeline"></param>
        /// <param name="centerPosition"></param>
        /// <param name="color"></param>
        public DrawCall CreateRectangleTextured()
        {
            return this.RectangleTexturedDrawCall;
        }
    }
}
